package de.playmee;

import de.playmee.Weather.Condition;
import de.playmee.dialogs.ProgressWheelDialog;
import de.playmee.handler.AccountHandler;
import de.playmee.handler.ChannelHandler;
import de.playmee.handler.MusicHandler;
import de.playmee.handler.PlaylistHandler;
import de.playmee.services.MusicService;
import de.playmee.services.MusicService.DataChangeListener;
import de.playmee.tasks.ComputePlaylistTask;
import de.playmee.tasks.ComputePlaylistTask.PlaylistComputedListener;
import de.playmee.tasks.UpdateWeatherConditionsTask.WeatherUpdatedListener;
import de.playmee.views.CoverFlow;
import de.playmee.views.CoverFlowAdapter;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class PlayerActivity extends MainMenuActivity implements
		OnClickListener, DataChangeListener, PlaylistComputedListener {
	
	private final int ART_SIZE = 150; // size in dp
	
	private Playmee application;
	
	private ProgressWheelDialog progressWheelDialog;
	
	// needed because onItemSelectedListener is called after resuming activity
	// and player should not start automatically (e.g. after screen saver)
	private boolean isUserCommand;
	
	private Weather weather;
	
	private ImageButton weatherButton;
	private TextView channelText;

	private Button playButton;
	private Button pauseButton;
	private Button rewindButton;
	//private Button skipButton;
	private Button stopButton;

	private TextView trackText;
	private ImageView trackArt;
	private CoverFlow coverFlow;
	
	private MusicHandler mHandler;
	private ChannelHandler cHandler;
	private PlaylistHandler pHandler;
	private AccountHandler aHandler;

	/**
	 * called when the activity is first created
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.player);
		
		application = (Playmee) getApplication();
		mHandler = application.getMusicHandler();
		cHandler = application.getChannelHandler();
		pHandler = application.getPlaylistHandler();
		aHandler = application.getAccountHandler();
		application.addDataChangeListener(this);
		
		progressWheelDialog = new ProgressWheelDialog(this);
		
		// add WeatherUpdateListener
		weather = application.getWeather();
		application.addWeatherUpdatedListener(new WeatherUpdatedListener() {
			@Override
			public void onWeatherUpdated(Condition condition) {
				updateAfterWeatherChanged(condition);
			}
		});
		
		// get weather button
		weatherButton = (ImageButton) findViewById(R.id.player_weatherButton);
		weatherButton.setClickable(false);
		weatherButton.setBackgroundColor(android.R.color.transparent);
		/*
		weatherButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Condition[] conditions = Condition.getArray();
				Condition c;
				Random r = new Random();
				do {
					c = conditions[r.nextInt(conditions.length)];
				} while(c == weather.getCurrentWeather());
				updateAfterWeatherChanged(c);
			}
		});
		*/
		
		// get channel
		channelText = (TextView) findViewById(R.id.player_channel);

		// get buttons
		playButton = (Button) findViewById(R.id.playbutton);
		pauseButton = (Button) findViewById(R.id.pausebutton);
		//skipButton = (Button) findViewById(R.id.skipbutton);
		rewindButton = (Button) findViewById(R.id.rewindbutton);
		stopButton = (Button) findViewById(R.id.stopbutton);

		playButton.setOnClickListener(this);
		pauseButton.setOnClickListener(this);
		//skipButton.setOnClickListener(this);
		rewindButton.setOnClickListener(this);
		stopButton.setOnClickListener(this);

		// get track views
		trackText = (TextView) findViewById(R.id.player_track);
		trackArt = (ImageView) findViewById(R.id.player_art);
		
		// create cover flow
		LinearLayout layout = (LinearLayout) findViewById(R.id.player_layout);
		coverFlow = new CoverFlow(this);
		//coverFlow.setLayoutParams(new LayoutParams(100, 100));
		coverFlow.setSpacing(-25);
		coverFlow.setSelection(2, true);
		coverFlow.setAnimationDuration(1000);
		coverFlow.setCallbackDuringFling(false);
		coverFlow.setOnItemSelectedListener(new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
				if (isUserCommand) {
					Intent i = new Intent(MusicService.ACTION_PLAY_POS);
					i.putExtra("pos", position);
					startService(i);
				} else {
					isUserCommand = true;
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				// do nothing
			}
		});
		layout.addView(coverFlow, 1);
		
		initChannelDetails();
		initCoverView();
	}

	@Override
	protected void onResume() {
		super.onResume();
		isUserCommand = false;
		updateTrackDetails();
		initChannelDetails();
		initCoverView();
	}
	
	private void initChannelDetails() {
		// initialize weather button
		Condition currentWeatherCondition = weather.getCurrentWeather();
		if (currentWeatherCondition != null) {
			weatherButton.setImageResource(Condition.getResId(currentWeatherCondition));
		}
		
		// initialize channel text
		Playlist currentPlaylist = pHandler.getCurrentPlaylist();
		if (currentPlaylist == null || currentPlaylist.getTrackIds().isEmpty()) {
			channelText.setText("No channel selected.");
		} else {
			Long currentChannelId = pHandler.getCurrentPlaylist().getChannelId();
			channelText.setText(cHandler.loadChannel(currentChannelId).getLabel());
			
		}
	}
	
	private void initCoverView() {
		Playlist currentPlaylist = pHandler.getCurrentPlaylist();
		if (currentPlaylist == null || currentPlaylist.getTrackIds().isEmpty()) {
			// hide CoverFlow and show dummy art
			coverFlow.setVisibility(CoverFlow.GONE);
			trackArt.setVisibility(ImageView.VISIBLE);
		} else {
			// hide dummy art and show CoverFlow
			trackArt.setVisibility(ImageView.GONE);
			coverFlow.setVisibility(CoverFlow.VISIBLE);
			
			// create new cover flow adapter
			CoverFlowAdapter coverFlowAdapter = new CoverFlowAdapter(this,
					mHandler, currentPlaylist, application.dpToPx(ART_SIZE));
			coverFlow.setAdapter(coverFlowAdapter);
			
			// sets the cover flow to the correct position
			int pos = currentPlaylist.getCurrentPos();
			if (pos == -1) pos = 0;
			coverFlow.setSelection(pos);
		}
	}
	
	/**
	 * updates trackText and trackArt (uses data of the current track)
	 */
	private void updateTrackDetails() {
		Track currentTrack = pHandler.getCurrentTrack();
		if (currentTrack != null) {
			trackText.setText(currentTrack.getArtist() + "\n" + currentTrack.getTitle());
			mHandler.loadAlbumArt(currentTrack);
		}
	}
	
	/**
	 * updates views and the playlist when the current weather conditions have changed
	 * 
	 * @param condition
	 * @param channel
	 */
	private void updateAfterWeatherChanged(Condition condition) {
		Toast.makeText(PlayerActivity.this, "Current weather conditions: " + condition,
				Toast.LENGTH_SHORT).show();
		
		// update weather button
		weatherButton.setImageResource(Condition.getResId(condition));
		
		// update playlist
		Playlist currentPlaylist = pHandler.getCurrentPlaylist();
		if (currentPlaylist != null) {
			long currentChannelId = currentPlaylist.getChannelId();
			Channel currentChannel = cHandler.loadChannel(currentChannelId);
			// only update if channel is considering weather conditions
			if (currentChannel.isConsideringWeather()) {
				progressWheelDialog.show();
				Playmee application = (Playmee) getApplication();
				boolean hasNetworkConnection = application.hasNetworkConnection();
				// only update if we are connected to the internet
				if (hasNetworkConnection) {
					Weather weather = application.getWeather();
					weather.setCurrentWeather(condition);
					new ComputePlaylistTask(aHandler, pHandler, currentChannel, hasNetworkConnection, weather, this).execute();
				}
			}
		}
	}
	
	@Override
	public void onPlaylistComputed(Playlist pl) {
		// TODO keep current track playing
		pHandler.setCurrentPlaylist(pl);
		initCoverView();
		progressWheelDialog.dismiss();
	}

	public void onClick(View target) {
		// send intent to the MusicService, according to the button that was clicked
		if (target == playButton) {
			startService(new Intent(MusicService.ACTION_PLAY));
		}
		else if (target == pauseButton) {
			startService(new Intent(MusicService.ACTION_PAUSE));
		}
		//else if (target == skipButton) {
			//startService(new Intent(MusicService.ACTION_SKIP));
		//}
		else if (target == rewindButton) {
			startService(new Intent(MusicService.ACTION_REWIND));
		}
		else if (target == stopButton) {
			startService(new Intent(MusicService.ACTION_STOP));
		}
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		switch (keyCode) {
		case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
		case KeyEvent.KEYCODE_HEADSETHOOK:
			startService(new Intent(MusicService.ACTION_TOGGLE_PLAYBACK));
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public void onTrackChanged(Track track) {
		updateTrackDetails();
		coverFlow.setSelection(pHandler.getCurrentPlaylist().getCurrentPos());
	}

	@Override
	public void onChannelChanged(Channel channel) {
		channelText.setText(channel.getLabel());
	}
}
